home *** CD-ROM | disk | FTP | other *** search
Wrap
/* * Copyright (c) 1990, 1991 Stanford University * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the name * Stanford may not be used in any advertising or publicity relating to * the software without the specific, prior written permission of * Stanford. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* $Header: /Source/Media/collab/TimeLine/RCS/openApps.c,v 1.1 92/01/09 16:26:43 drapeau Exp $ */ /* $Log: openApps.c,v $ * Revision 1.1 92/01/09 16:26:43 drapeau * Made slight modifications to make code more ANSI-compliant. * * Revision 1.0 91/09/30 17:02:09 chua * Update to version 1.0 * * Revision 0.77 91/09/26 18:03:47 chua * In OpenAppsInitialize, change the add parameter to load. When load = 0, * the function is being called from the OpenHandler. If any applications in * the current instrument list is not open, it will be launched by calling * GetPortFromName. Only if this fails will the application be muted. * * Revision 0.76 91/09/25 13:51:13 chua * Changed the instrument field, instInfo, to editInfo. * Changed InstrumentInfo to EditInfo. * * Revision 0.75 91/09/19 18:32:04 chua * Removed the DestroyPortArray statement in OpenAppsInitialize as this causes * segmentation fault due to the ports being freed. * * Revision 0.74 91/09/19 17:29:01 chua * Make sure that variables are initialized properly. Change formatting slightly, * so that (if, for, while) statements with only one statement in them will not have * braces. * * Revision 0.73 91/09/17 17:17:36 chua * In DeleteAppsHandler, reassign the PANEL_CLIENT_DATA of the notes info list * to the new positions of those applications which have changed their * positions due to the deletion. * * Revision 0.72 91/09/16 15:10:42 chua * Rewrote the OpenAppsInitialize and UpdateAppsHandler routines so that when doing an * update apps application, the notes that are currently on the TimeLine are not erased. * The OpenAppsInitialize would also be smart enough to fill in the applications on the * existing instrument list with the port numbers of the applications obtained from the * Port Manager. * * Revision 0.71 91/09/09 14:57:09 chua * In OpenAppsInitialize, if the appname is TimeLine, do not include in the instrument list. * Previously, if the appname is TimeLine but the hostname is different, it will be * included. This is just a temporary measure. Once the receiver protocol is implemented * in the TimeLine, other TimeLines will be included in the instrument list. * * In OpenAppsFindIcon, there was an error in allocating space to appIcon. It should be * sizeof (IconData) instead of sizeof(appIcon). * * Revision 0.70 91/09/04 15:11:05 chua * In OpenAppsFindIcon, if GetAppIcon does not return the proper icon bits, * return the unknownIcon. * * Revision 0.69 91/08/27 18:18:33 chua * In DeleteAppHandler, before doing a DestroySender, check that the * application is still alive. * * Revision 0.68 91/08/26 14:22:04 chua * Removed the tlFrame->actualApps variable. * * Revision 0.67 91/08/22 15:03:32 chua * A minor formatting change in line 183. * * Revision 0.66 91/08/22 12:10:29 chua * In the OpenAppsFindIcon function, before doing a NewSender to check if an application is * open, make sure that it was previously open first. * * Revision 0.65 91/08/21 16:58:35 chua * In OpenAppsFindIcon, send a SenderGetAppIcon message to the application to get * its icon. If this fails, then look in the graphics directory for the icon file. * * Revision 0.64 91/08/19 19:20:39 chua * In the UpdateAppsHandler, do a DestroySender for the old instrument list nodes. * * Revision 0.63 91/08/16 17:02:35 chua * In the UpdateAppsHandler, reset the filename to 'untitled'. * * Revision 0.62 91/08/08 15:47:49 chua * In UpdateAppsHandler, replace return NULL by return item * * Revision 0.61 91/08/08 14:27:27 chua * In OpenAppsFindIcon, since TimeLineHome now points directly to the graphics directory * instead of its parent, make the appropriate changes when trying to find the icon. * * Revision 0.60 91/08/05 16:53:27 chua * Deleted the RepaintCanvas routine, as it is no longer necessary. In places where it * is called, just call the ScrollToFirstQuarter routine, which will do the necessary * repaint as well. * * Revision 0.59 91/07/17 16:34:49 chua * Reformatted the braces for the switch statements. * * Revision 0.58 91/07/17 10:32:21 chua * In the OpenAppsFindIcon function, first check if the icon file can be found before * attempting to create a server image with it. This is to prevent a XView error * message from appearing if the icon is not found. * * Revision 0.57 91/07/09 17:02:17 chua * Removed some redundant variables. * * Revision 0.56 91/06/26 16:48:09 chua * In the OpenAppsInitialize routine, check also that the hostname is not equal to "localhost" in * line 134. This is because the default host is now "localhost". * * Revision 0.55 91/06/25 17:52:20 chua * Added two new functions, which are the menu handlers for the Show Application and Hide Application * menu items found under the Application menu button. * * Show Application will move the media editor to the front of the screen, and Hide Application will * iconify it. * * Revision 0.54 91/06/04 17:37:25 chua * Added the copyright comments in the beginning of the file. * * Revision 0.53 91/06/04 10:43:53 chua * Added a call to UpdateHeader to update the header of the frame whenever * there is a change in the status of the change flag. * * Revision 0.52 91/06/03 11:12:02 chua * Make changes to accomodate multiple documents. This involves identifying * which is the current active window, that is, the one where the last mouse * click was done. * * Revision 0.51 91/05/28 12:15:18 chua * * * Revision 0.50 91/05/24 16:37:22 chua * Added the code for the DeleteAppHandler. Please refer to the comments * header for the function on how it works. * * Revision 0.49 91/05/23 17:39:07 chua * *** empty log message *** * * Revision 0.48 91/05/22 16:42:02 chua * * * Revision 0.47 91/05/22 13:59:35 chua * * * Revision 0.46 91/05/22 11:47:00 chua * * * Revision 0.45 91/05/17 16:58:53 chua * *** empty log message *** * * Revision 0.44 91/05/17 16:58:10 chua * *** empty log message *** * * Revision 0.43 91/05/17 16:57:08 chua * *** empty log message *** * * Revision 0.42 1991/04/24 01:10:22 chua * In the UpdateAppsHandler, the section of code dealing with freeing all the instrument nodes is * replaced by a call to the FreeInstrumentList function. * * In the ShowNotesInfoHandler, the call to InitInstInfoWindow is replaced by ShowInfoWindow, * since the pop-up window will have already been created (in InstrumentNew) and we only need * to bring it up to the front and be visible. * * Revision 0.41 1991/04/08 21:29:33 chua * In the UpdateAppsHandler, when freeing each instrument, destroy the info pop-up window as well if it has been * created. * * A new menu option for the Applications menu button has been added. This is the ShowNotesInfoHandler * function. This function first checks if an application has been selected. If so, it will call the * InitInstInfoWindow to display the info pop-up window. * * Revision 0.40 1991/04/01 03:44:52 chua * This file contains functions which deal with asking the PortManager for a list of its open applications. * The functions are: * OpenAppsInitialize - ask the PortManager for a list of open applications and build an instrument list for * these applications (one application being represented by an instrument). * OpenAppsFindIcon - gets the icon file for the application and create a server image for it. This function * is called by InstrumentDrawIcon (instrument.c) which does the actual drawing of the * icon on the screen. * UpdateAppsHandler - ask the PortManager for its current list of open applications and reconstruct the * instrument list of the TimeLine Editor. This function is used when either some * applications have died or some new ones were launched since the TimeLine Editor was * first ran. * DeleteAppsHandler - not implemented yet. * */ static char openappsrcsid[] = "$Header: /Source/Media/collab/TimeLine/RCS/openApps.c,v 1.1 92/01/09 16:26:43 drapeau Exp $"; #include "main.h" #include <sys/stat.h> Instrument *instHead; /* Pointer to the head of the instrument list */ char TimeLineHost[MAXHOSTNAMELEN]; /* Host from where the TimeLine Editor is launched */ /* * This function will ask the Port Manager for the list of open applications that is registered with it. * With the information from the Port Manager, it will form an instrument list, which is used to store information about the instrument as well as * keep track of new notes added to the instrument in future by the user. * If an instrument list already exist, an attempt is made to find a match in port number between the apps on the instrument list and those on the list * given by the port manager. If such a match could not be found, check for a match in application name. If that fails, mute the application on the * instrument list that could not be matched. However, if load = 0, indicating that this function was called from OpenHandler, call * SenderGetPortFromName to launch the application. Only if this fails will the application be muted. * Add the applications on the port manager list that has no equivalent app on the instrument list. * The parameter load indicates if unassigned ports should be added to the instrument list. This is usually desirable, except when opening a file, * when we only want to see the apps which existed when the file was saved. Thus, when opening a file, load = 0. If load = 0, this will also * launch any application in the file that is currently not opened. * Called by TimeLineInit (TimeLine.c) and UpdateAppsHandler (openApps.c) */ void OpenAppsInitialize(tlFrame, load) TimeLineFramePtr tlFrame; int load; { int i, j; int found; int result; PortArray *appsOpen = (PortArray *) NULL; /* Array to store the list of open applications and their port information */ PortArray *appsNew = (PortArray *) NULL; /* Array to store the a newly opened app launched by GetPortFromName */ Port appPort; Instrument *instrument; Instrument *multipleInst; int *portUsed; /* Keep track of which port has already been assigned to the instrument list */ int count; /* Keep track of how many copies of the same app exist in the instrument list */ result = SenderGetOpenApps(tlFrame->TimeLineSender, &appsOpen); /* Get list of open applications from the PortManager */ if (result == -1) return; portUsed = (int *) malloc (sizeof (int) * appsOpen->numberOfPorts); for (i = 0; i < appsOpen->numberOfPorts; i++) portUsed[i] = 0; instrument = tlFrame->instHead; for (i = 0; i < tlFrame->numberOfApps; i++) { j = 0; found = 0; while (j < appsOpen->numberOfPorts && !found) /* Check if there is a match in port number */ { if (instrument->port->portNumber == appsOpen->portArray[j].portNumber) { found = 1; portUsed[j] = 1; } else j ++; } if (found == 0) /* Check if there is a match in application name */ { j = 0; while (j < appsOpen->numberOfPorts && !found) /* Check if there is a match in port number */ { if (strcmp(instrument->port->appName, appsOpen->portArray[j].appName) == 0 && portUsed[j] == 0) { if ((instrument->sender = NewSender(appsOpen->portArray+j)) != NULL) /* Check if sender to the application can be created */ { if (strcmp(instrument->port->hostName, "App not open") == 0) /* Check if app was previously not open */ { xv_set(instrument->editInfo->MuteChoice, PANEL_VALUE, 0, NULL); /* Unmute the app */ xv_set(instrument->editInfo->MuteChoice, PANEL_INACTIVE, FALSE, NULL); } strcpy(instrument->port->hostName, appsOpen->portArray[j].hostName); instrument->port->portNumber = appsOpen->portArray[j].portNumber; xv_set(instrument->editInfo->HostnameText, /* Set the hostname on the pop-up window */ PANEL_LABEL_STRING, instrument->port->hostName, NULL); instrument->icon = (Pixmap) xv_get(OpenAppsFindIcon(instrument), /* Get the pixmap image of the icon */ SERVER_IMAGE_PIXMAP); found = 1; portUsed[j] = 1; } else j++; } else j ++; } } if (!found) /* Mute the application, as there is no equivalent app checked in */ { result = -1; if (load == 0) /* Try to launch the application by calling SenderGetPortFromName */ { multipleInst = tlFrame->instHead; count = 1; while (multipleInst != instrument) { if (strcmp(multipleInst->port->appName, instrument->port->appName) == 0) count ++; multipleInst = multipleInst->next; } appPort.appName = (char *) malloc (MAXPATHLEN); strcpy(appPort.appName, instrument->port->appName); appPort.hostName = "localhost"; result = SenderGetPortFromName(tlFrame->TimeLineSender, &appPort, &appsNew); if (result == 0 && appsNew) /* Get port is successful */ if (appsNew->numberOfPorts < count) /* Check if we need to force launch a new application */ { DestroyPortArray(appsNew); appPort.hostName = LaunchNewApp; result = SenderGetPortFromName(tlFrame->TimeLineSender, &appPort, &appsNew); } if (result == 0 && appsNew) /* Get port is successful */ if (appsNew->numberOfPorts > 0) if ((instrument->sender = NewSender(appsNew->portArray+(count - 1))) != NULL) /* Check if sender to the application can be created */ { strcpy(instrument->port->hostName, appsNew->portArray[count - 1].hostName); instrument->port->portNumber = appsNew->portArray[count - 1].portNumber; xv_set(instrument->editInfo->HostnameText, /* Set the hostname on the pop-up window */ PANEL_LABEL_STRING, instrument->port->hostName, NULL); instrument->icon = (Pixmap) xv_get(OpenAppsFindIcon(instrument), /* Get the pixmap image of the icon */ SERVER_IMAGE_PIXMAP); tlFrame->chosenApp = i; HideApplicationHandler(tlFrame->TimeLine_window->appButton, MENU_NOTIFY); /* Iconify the application */ tlFrame->chosenApp = -1; } } if (result == -1 || load == 1) { xv_set(instrument->editInfo->MuteChoice, PANEL_VALUE, 1, NULL); /* Mute the app */ xv_set(instrument->editInfo->MuteChoice, PANEL_INACTIVE, TRUE, NULL); strcpy(instrument->port->hostName, "App not open"); xv_set(instrument->editInfo->HostnameText, /* Set the hostname on the pop-up window */ PANEL_LABEL_STRING, instrument->port->hostName, NULL); } } instrument = instrument->next; } if (load == 1) /* Check if we want to add the unassigned apps to the instrument list */ { for (i = 0; i < appsOpen->numberOfPorts; i++) /* Add the remaining unassigned ports (which are not TimeLine apps to */ { /* the instrument list */ if (strcmp(appsOpen->portArray[i].appName, TimeLineName) != 0 && /* Check that the application is not a TimeLine Editor */ portUsed[i] == 0) /* Check that the port is not already assigned */ AddInstrument(appsOpen->portArray+i, tlFrame); } } free (portUsed); DestroyPortArray(appsNew); DestroyPortArray(appsOpen); } /* * This function takes an instrument. * First, it tries to ask the application to send the icon bits over the network. * If this fails, it gets the name of the application and attempts to find the bitmap icon file for * it in the graphics directory. If successful, it converts this file into a server bitmap image and returns it. * Called by InstrumentDrawIcon (instrument.c) */ Server_image OpenAppsFindIcon(instrument) Instrument *instrument; { Server_image icon; IconData *appIcon; Sender *sender; int result; appIcon = (IconData *) malloc (sizeof(IconData)); appIcon->iconData = (char *) 0; appIcon->dataLength = 0; sender = NULL; if (strcmp(instrument->port->hostName, "App not open") != 0) sender = NewSender(instrument->port); /* Check if the application is still alive */ if (sender != NULL) { result = SenderGetAppIcon(instrument->sender, &(appIcon)); /* If the get app icon fails, return the unknown icon */ if (result == -1) return unknownIcon; DestroySender(sender); } if (appIcon->dataLength > 0) icon = (Server_image) xv_create(NULL, SERVER_IMAGE, SERVER_IMAGE_BITS, appIcon->iconData, SERVER_IMAGE_DEPTH, 1, XV_WIDTH, 64, XV_HEIGHT, 64, NULL); else icon = unknownIcon; return icon; } /* * Menu handler for `AppMenu (Update Applications List)'. * This function will update the instrument list with a list from the port manager. It will attempt to merge the two list together (in OpenAppsInitialize). * The canvas height is set according to the number of open applications and the repaint canvas procedure is called to show all the new * applications. */ Menu_item UpdateAppsHandler(item, op) Menu_item item; Menu_generate op; { TimeLineFramePtr tlFrame; TimeLine_window_objects *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)]; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: OpenAppsInitialize(tlFrame, 1); /* Get the new list of open applications from the Port Manager */ SetCanvasHeight(tlFrame); AppCanvasRepaintHandler(tlFrame->TimeLine_window->AppCanvas, tlFrame->paintWinApp, tlFrame->dpyApp, tlFrame->xidApp, NULL); break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `AppMenu (Delete an application)'. * This function will delete an instrument from the instrument. The instrument should have been selected on the AppCanvas, or else no action is taken. * First, check to see which instrument is to be deleted. * Next, decrement the number of instruments counters. * Update the positions of the instruments following the deleted one on the list, so that they are shifted up by 1 in terms of their relative position. * Free the space allocated to the deleted instrument. * Set the new canvas height and redraw the canvas. */ Menu_item DeleteAppHandler(item, op) Menu_item item; Menu_generate op; { Instrument *instrument, *prevInst; Instrument *nextInst; Note *note, *nextNote; Sender *sender; TimeLineFramePtr tlFrame; TimeLine_window_objects *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)]; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: if (tlFrame->chosenApp >= 0) { instrument = (Instrument *) FindInstrument (tlFrame->chosenApp, tlFrame); /* Instrument to be deleted */ if (instrument == NULL) return item; nextInst = instrument->next; if (tlFrame->chosenApp == 0) tlFrame->instHead = tlFrame->instHead->next; else { prevInst = (Instrument *) FindInstrument (tlFrame->chosenApp - 1, tlFrame); /* The instrument before the one to be deleted */ prevInst->next = instrument->next; } tlFrame->numberOfApps --; /* Decrement the total number of applications count */ while (nextInst != NULL) /* Update the positions of the instruments following the deleted instrument */ { /* (Shift up by 1) */ nextInst->relativePosition --; xv_set(nextInst->editInfo->NoteInfoList, /* Attach the instrument's relative position as the PANEL_CLIENT_DATA. */ PANEL_CLIENT_DATA, nextInst->relativePosition, /* Lets the program know which instrument the panel belongs to. */ NULL); nextInst->cableStart = (IconHeight + IconGap) * nextInst->relativePosition + FirstCableYPosition; nextInst = nextInst->next; } note = instrument->firstNote; /* Free the space allocated to the deleted instrument and its notes */ nextNote = instrument->firstNote; while (nextNote != NULL) /* Free the notes */ { nextNote = note->next; free (note); note = nextNote; } xv_destroy_safe(instrument->editInfo->EditInfoWindow); /* Free the edit pop-up window */ if (strcmp(instrument->port->hostName, "App not open") != 0) { sender = NewSender(instrument->port); if (sender != NULL) { DestroySender(instrument->sender); DestroySender(sender); } } free (instrument); tlFrame->chosenApp = -1; SetCanvasHeight(tlFrame); /* Set the new canvas height and redraw the canvas */ AppCanvasRepaintHandler(tlFrame->TimeLine_window->AppCanvas, tlFrame->paintWinApp, tlFrame->dpyApp, tlFrame->xidApp, NULL); ScrollToFirstQuarter(tlFrame, 0, 1); } break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `AppMenu (Show edit info for an application)'. * This function displays the instrument info pop-up window. */ Menu_item ShowEditInfoHandler(item, op) Menu_item item; Menu_generate op; { Instrument *currentInst; TimeLineFramePtr tlFrame; TimeLine_window_objects *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)]; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: if (tlFrame->chosenApp >= 0) /* Check if an application is selected */ { currentInst = (Instrument *) FindInstrument(tlFrame->chosenApp, tlFrame); /* Get pointer to the currently chosen instrument node */ ShowInfoWindow(currentInst, tlFrame); /* Show the pop up info window */ } break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `AppMenu (Hide application)'. * This function will send the SenderHideApplication message to the selected application, which will then take the appropriate action to hide itself. * Hiding means iconifying here. */ Menu_item HideApplicationHandler(item, op) Menu_item item; Menu_generate op; { Instrument *instrument; TimeLineFramePtr tlFrame; TimeLine_window_objects *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)]; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: if (tlFrame->chosenApp >= 0) { instrument = (Instrument *) FindInstrument(tlFrame->chosenApp, tlFrame); if (instrument == NULL) return item; if (CheckAppOpen(tlFrame, instrument, 2) == Error) return item; SenderHideApplication(instrument->sender); } break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `AppMenu (Show application)'. * This function will send the SenderShowApplication message to the selected application, which will then take the appropriate action to show itself. */ Menu_item ShowApplicationHandler(item, op) Menu_item item; Menu_generate op; { Instrument *instrument; TimeLineFramePtr tlFrame; TimeLine_window_objects *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)]; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: if (tlFrame->chosenApp >= 0) { instrument = (Instrument *) FindInstrument(tlFrame->chosenApp, tlFrame); if (instrument == NULL) return item; if (CheckAppOpen(tlFrame, instrument, 2) == Error) return item; SenderShowApplication(instrument->sender); } break; case MENU_NOTIFY_DONE: break; } return item; }